//实现温度到数码管，温度到串口的转换
module ctrl (
    input       [15:0]      t_data  ,//输入温度数据，两字节，前5位为符号位，
    output      [23:0]      dis_data,//输出数码管
    output                  uart_en ,//定时10s，串口开启输出
    output                  en      ,//输出en信号，判断温度阈值，超过了为1，没超过为0
    output  reg [7:0]       uart_data    ,
    input                   clk     ,
    input                   rst_n    
);
    
    wire        [23:0]      data_b      ;
    wire        [3:0]       data_b001   ;   //小数点后的第三位
    wire        [3:0]       data_b01    ;   //小数点后的第二位
    wire        [3:0]       data_b1     ;   //小数点后的第一位
    wire        [3:0]       data_1      ;   //个位
    wire        [3:0]       data_10     ;   //十位
    wire        [3:0]       data_fu     ;   //符号位

    assign data_b       = t_data[10:0] * 625; //放大1000倍 数据乘以精度 才是温度，因为浮点数无法表示
    assign data_b001    = data_b /10 %10    ;
    assign data_b01     = data_b /100 %10   ;      
    assign data_b1      = data_b /1000 %10  ;
    assign data_1       = data_b /10000 %10 ;
    assign data_10      = data_b /100000 %10;
    assign data_fu      = t_data[11] ? 4'hB : 4'hA; //数码管上A的话就显示正号 B的话就显示负号


    assign dis_data = {data_fu,data_10,data_1,data_b1,data_b01,data_b001};//连续赋值,给数码管

    assign en = ( data_1 >=4'd0 && data_10 >= 4'd3)?1'b1 :1'b0;//如果温度大于30度就报警。

    parameter   TIME_10S = 500_000_000;
    reg         [28:0]      cnt10S    ;   //10s计数
    wire                    add_cnt10S;
    wire                    end_cnt10S;

    parameter   TYPE = 15;
    reg         [3:0]       cnt_type;   //发送15个数据s
    wire                    add_cnt_type;
    wire                    end_cnt_type;

    //保持10s计数完成的状态
    reg                     flag    ;
    assign uart_en = add_cnt_type   ;

    //连续发送12个字符的间隔设定为200us
    parameter   TIME_200uS = 1_000_0;
    reg         [13:0]      cnt_200uS;
    wire                    add_cnt_200uS;   
    wire                    end_cnt_200uS;

    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            cnt_200uS <= 0;
        end 
        else if(add_cnt_200uS)begin 
            if(end_cnt_200uS)begin 
                cnt_200uS <= 0;
            end
            else begin 
                cnt_200uS <= cnt_200uS + 1;
            end 
        end
        else begin
            cnt_200uS <= cnt_200uS;
        end
    end 
    assign add_cnt_200uS = 1'b1;
    assign end_cnt_200uS = add_cnt_200uS && cnt_200uS ==  TIME_200uS - 1;

    //检测是否达到了10s，如果到达，就flag为1进而开始发送数据，如果发送完12个数据flag就等于0
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            flag <= 0;
        end 
        else if(end_cnt10S)begin 
            flag <= 1;
        end 
        else if(end_cnt_type)begin
            flag <= 0;
        end
        else begin 
            flag<=flag;
        end 
    end

    //10s计数器
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            cnt10S <= 0;
        end 
        else if(add_cnt10S)begin 
            if(end_cnt10S)begin 
                cnt10S <= 0;
            end
            else begin 
                cnt10S <= cnt10S + 1;
            end 
        end
        else begin
            cnt10S <= cnt10S;
        end
    end 
    assign add_cnt10S = 1'b1;
    assign end_cnt10S = add_cnt10S && cnt10S ==  TIME_10S - 1;//只会保持一个时钟周期


    //定义cnt_type如何变化,记录发送到12个中的第几个了。
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            cnt_type <= 0;
        end 
        else if(add_cnt_type)begin 
            if(end_cnt_type)begin 
                cnt_type <= 0;
            end
            else begin 
                cnt_type <= cnt_type + 1;
            end 
        end
        else begin
            cnt_type <= cnt_type;
        end
    end 
    assign add_cnt_type = flag && end_cnt_200uS;//什么时候开始传送12个数据,10s到达后，并且两次串口间隔200us结束
    assign end_cnt_type = add_cnt_type && cnt_type ==  TYPE - 1;

    always @(*) begin
        if(flag)begin
            case(cnt_type)//当前发送了几个字符了
                0   :   uart_data = 8'b01010100; //"T",ascall值为84
                1   :   uart_data = 8'b01100101; //"e"，ascall值为101
                2   :   uart_data = 8'b01101101;//"m",109
                3   :   uart_data = 8'b01110000;//"p",112
                4   :   uart_data = 8'b00111010;//":",58
                5   :   uart_data = data_fu == 4'hB ?8'b00101101:8'b00101011;//正负号
                6   :   uart_data = data_10+10'd48;//将数字转换成字符
                7   :   uart_data = data_1+10'd48;
                8   :   uart_data = 8'b00101110;//"."
                9   :   uart_data = data_b1+10'd48;
                10   :   uart_data = data_b01+10'd48;
                11  :   uart_data = 8'b01100000;//"`"
                12  :   uart_data = 8'b01000011;//"C"
                13  :   uart_data = 8'b00111011;//";"
                14  :   uart_data = 8'b00001101;//"/r"
                15  :   uart_data = 8'b00001010;//"/n"
                default :   uart_data = 8'b01011000;
            endcase
        end
    end


    

endmodule